// ps:代码参考官解
// 学习点：/10，%10
package main

import "fmt"

func main() {
	link1 := listToLink([]int{9, 9, 9, 9, 9, 9, 9})
	link2 := listToLink([]int{9, 9, 9, 9})
	resLinkNode := addTwoNumbers(link1, link2)
	printLink(resLinkNode)
}

type ListNode struct {
	Val  int
	Next *ListNode
}

func addTwoNumbers(l1 *ListNode, l2 *ListNode) *ListNode {
	head := &ListNode{}
	cur := head
	carry := 0
	// golang没有while函数，是通过for循环替换实现的
	for l1 != nil || l2 != nil {
		// 不能放在外面
		n1, n2 := 0, 0
		if l1 != nil {
			n1 = l1.Val
			l1 = l1.Next
		}
		if l2 != nil {
			n2 = l2.Val
			l2 = l2.Next
		}
		sum := n1 + n2 + carry
		carry = sum / 10
		//这样写无法实现循环重置carry
		//if sum >= 10 {
		//	carry = 1
		//}
		cur.Next = &ListNode{Val: sum % 10}
		cur = cur.Next
	}
	// 最后的进位判断需要处理
	if carry == 1 {
		cur.Next = &ListNode{Val: 1}
	}
	return head.Next
}

func listToLink(nums []int) *ListNode {
	// 哑节点dummy，记录链表头地址
	head := &ListNode{}
	// 追踪当前节点
	cur := head
	for _, v := range nums {
		// 添加新节点
		cur.Next = &ListNode{Val: v}
		// 移动节点
		cur = cur.Next
	}
	// 返回头节点的下一个节点，即链表的第一个实际数据节点
	return head.Next
}

func printLink(listNode *ListNode) {
	for listNode != nil {
		fmt.Printf("%v ", listNode.Val)
		listNode = listNode.Next
	}
}
